local vector2d = require("Vector2D")


Gravity = class('Gravity');
Gravity.static.maxVelocityPlanet = 300
Gravity.static.maxVelocityFlight = 700
Gravity.static.gravity_constant = 18000
Gravity.static.atmFriction = 0.99
--density = 0.4

function Gravity.static.gravity(player,planet,inPlanet)
    local forceV = vector2d:Sub(planet:getVector(),player:getVector())
    local distance = forceV:magnitude()
    -- vector fuerza
    forceV:normalize()
    -- magnitud de la fuerza
    local forceM = Gravity.gravity_constant * planet.gravity/ distance^2
    
    -- si el jugador esta en un planeta o su atmosfera
    if(inPlanet)then
        --si estamos saltando constante
        if(player.planet ~= nil)then
            forceM = 4;
        end
        --reduce la velocidad cuando entro en la atmosfera
        if(player.planet == nil)then
            local vp = player:getLinearVelocityVec()
            player:setLinearVelocity( vp.x * Gravity.atmFriction, vp.y * Gravity.atmFriction );
        end
    else
        -- estoy en vuelo, solo afectan los mas cercanos
        if(distance > 1000)then
            return
        end
    end
    
    forceV:mult(forceM)
    
    --show gravity vector
    if(debugMode)then
        local vd = forceV
        if(player.gVector ~= nil)then
            player.gVector:removeSelf()
        end
        player.gVector = display.newLine(player.body.parent, 0, 0, vd.x * 20, vd.y * 20)
        player.gVector:setColor(255,255,0)
        player.gVector:translate(player:getX(), player:getY())
    end
    
    player:applyForce(forceV.x, forceV.y, player:getX(), player:getY())
end


function Gravity.static.applyGravity(player, game)
    --si el jugador esta en un sensor de gravedad
    if(player.pVector ~= nil)then
        player:applyForce(player.pVector.x, player.pVector.y, player:getX(), player:getY())
        return
    end
    
    --
    -- Si el jugador esta en el planeta se aplica una gravedad constante
    --
    if(player.planet ~= nil)then
        Gravity.gravity(player,player.planet,true)
        return
    end
    
    --
    --  El jugador esta en vuelo, determinamos si esta en la atmosfera de algun/os planetas
    --
    local inPlanets = {}
    local j= 1
    local planetGroup = game[2]
    for i = 1, planetGroup.numChildren do
        local magnitud = MathUtils.dist(planetGroup[i],player:getVector())
        if(magnitud < planetGroup[i].cont.radio + planetGroup[i].cont.atmosfera + player.radio)then
            inPlanets[j]= planetGroup[i]
            j = j + 1
        end     
    end
    
    if(#inPlanets>0)then
        for i = 1, #inPlanets do
            Gravity.gravity(player,inPlanets[i].cont,true)             
        end
    else
        for i = 1, planetGroup.numChildren do
            Gravity.gravity(player,planetGroup[i].cont,false)         
        end
    end
    
    --
    -- Controlamos que no se supere la velocidad maxima
    --
    local vp = player:getLinearVelocityVec()
    if (vp:magnitude() > Gravity.maxVelocityFlight) then
        local desviacion = vp:magnitude()/Gravity.maxVelocityFlight;
        player:setLinearVelocity( vp.x /desviacion, vp.y/desviacion)
    end
end

function Gravity.static.applyGravityAtmosphere(object, game)
    --
    --  solo gravedad si esta en la atmosfera de algun/os planetas
    --
    local inPlanets = {}
    local j= 1
    local planetGroup = game[2]
    for i = 1, planetGroup.numChildren do
        local magnitud = MathUtils.dist(planetGroup[i],object:getVector())
        if(magnitud < planetGroup[i].cont.radio + planetGroup[i].cont.atmosfera + object.radio)then
            inPlanets[j]= planetGroup[i]
            j = j + 1
        end     
    end
    
    if(#inPlanets>0)then
        for i = 1, #inPlanets do
            Gravity.gravity(object,inPlanets[i].cont,true)             
        end
    end
end

function Gravity.static.jump(player)
    local vp = vector2d:Sub(player:getVector(),player.planet:getVector())
    vp:normalize()
    player:applyLinearImpulse(vp.x * 1.15, vp.y * 1.15, player:getX(), player:getY())
end


function Gravity.static.jumpI(player)
    local vp = vector2d:Sub(player:getVector(),player.planet:getVector())
    vp:normalize()
    player:applyLinearImpulse(vp.x * 0.95, vp.y * 0.95, player:getX(), player:getY())
end


function Gravity.static.speed(player)
    --velocidad en planeta
    local vp = vector2d:new(player:getLinearVelocity())
    
    if(debugMode)then
        --show velovity vector
        local vd = Vector2D:Normalize(vp)
        if(player.vVector ~= nil)then
            player.vVector:removeSelf()
        end
        player.vVector = display.newLine(player.body.parent, 0,0 , vd.x * 50, vd.y * 50)
        player.vVector:translate(player:getX(), player:getY())
    end
    
    if (player.mode == Player.RUN and vp:magnitude() < Gravity.maxVelocityPlanet/1.2) then
        local vlv = vector2d:new(player:getLinearVelocity())
        vlv:normalize()
        player:applyForce( vlv.x * 0.18, vlv.y * 0.18, player:getX(), player:getY() );
    elseif (player.planet ~= nil and vp:magnitude() > Gravity.maxVelocityPlanet) then
        local desviacion = vp:magnitude()/Gravity.maxVelocityPlanet;
        player:setLinearVelocity( vp.x/desviacion, vp.y/desviacion );
    end
end



